/******************************************************************************
 * 
 * 
 * This is the central element of the project.
 * It deals with the messages receive by the diffent input by processing it 
 * through a registered set of filter. 
 * May be, It can be usefull to have a class who can provide a particular 
 * management for an input. (for example : bluetooth research have to be re-run 
 * every 20sec, wifi every 40 sec, batterie level use listener and don't have to
 * be re-run...) 
 * 
 *  @author Mathieu Maret
 * 
 * 
 * 
 *****************************************************************************/

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Vector;

import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

public class EasyAwarenessManager {

	Vector input;
	Vector filter; 
	StorageManager dataStorage;


	/**
	 * Create a new manager without filter or input. A StorageManager is set as the Manager for the storage
	 * 
	 */
	public EasyAwarenessManager() {
		input = new Vector();
		filter = new Vector();
		dataStorage = new StorageManager();
	}

	/**
	 * Add a new message filter
	 * 
	 * @param f the filter
	 */
	public void addFilter(Filter f){
		filter.addElement((Object)f);
	}
	
	
	/**
	 * 
	 * Remove all the filter registered
	 * 
	 */
	public void remAllFilter(){
		filter.removeAllElements();
	}

	
	/**
	 * Remove a specific filter
	 * @param f the filter to remove
	 */
	public void remFilter(Filter f){
		filter.removeElement(f);
	}

	/**
	 * Add a input for the manager
	 * @param newInput the new input
	 */
	public void addInput(EasyAwarenessInput newInput){
		newInput.setManager(this);
		input.addElement((Object)newInput);
	}

	/**
	 * 
	 * Research an input by its type
	 * @param type the type of the input
	 * @return the EasyAwarnessInput corresponding to the type or null if not found
	 */
	public EasyAwarenessInput getInput(int type){
		EasyAwarenessInput output = null;
		for(int i = 0 ; i< input.size(); i++){
			if(((EasyAwarenessInput)input.elementAt(i)).getType() == type){
				output = (EasyAwarenessInput)input.elementAt(i);
			}
		}
		return output;
	}

	/**
	 * put the message through the different filters. If the filtre() methode of a filter return true for a message, this message will be given to the storage manager
	 * @param m A incomming message
	 */
	public synchronized void messageReceive(Message m){
		boolean hasBeenFilter = false;
		for(int i= 0; i< filter.size();i++){
			if(!hasBeenFilter && ((Filter)filter.elementAt(i)).filtre(m)){
				dataStorage.Store(m);
				hasBeenFilter = true;
			}
		}

	}

	public StorageManager getDataStorage() {
		return dataStorage;
	}

	public void setDataStorage(StorageManager dataStorage) {
		this.dataStorage = dataStorage;
	}

	
	/**
	 * provide a easy way for parsing simple xml.
	 * 
	 * @param xmlData The string containing the xml
	 * @param firstElement the name of the first element you want to parse
	 * @param element a vector containing in the order the element that will be found after the firstElement 
	 * @return return a Hashtable containing for all the element of the vetor element, the value of this element
	 * @throws IOException
	 * @throws XmlPullParserException
	 */
	public Hashtable parse(String xmlData, String firstElement,Vector element ) throws IOException, XmlPullParserException{
		Hashtable result = new Hashtable();
		KXmlParser parser = new KXmlParser();
		byte[] xmlByteArray = xmlData.getBytes();
		ByteArrayInputStream xmlStream = new 
		ByteArrayInputStream( xmlByteArray );
		InputStreamReader xmlReader = new 
		InputStreamReader( xmlStream );
		 parser.setInput( xmlReader );
		int i = 0;
		
		
		parser.nextTag();
		parser.require(XmlPullParser.START_TAG, null, firstElement);


		while(parser.nextTag() == XmlPullParser.START_TAG) {
		  parser.require(XmlPullParser.START_TAG, null, (String)element.elementAt(i));

		   // handle element content
		  // System.out.println("text content: "+ parser.nextText());
		  result.put((String)element.elementAt(i),parser.nextText());
		  parser.require(XmlPullParser.END_TAG, null, (String)element.elementAt(i));
		  i++;
		}

		parser.require(XmlPullParser.END_TAG, null, firstElement);
		return result;
	}


}
